namespace Microsoft.Robotics.Tracing
{
    /// <summary>
    /// Tracing context. Contains a string for a name, an ID and a parent context
    /// </summary>
    public sealed class TraceContext
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="TraceContext" /> class
        /// </summary>
        /// <param name="id">Log level id</param>
        /// <param name="text">Text value of the context. Will be pre-pended with parent's text ID followed by a dot</param>
        /// <param name="parentContext">Parent context</param>
        internal TraceContext(int id, string text, TraceContext parentContext)
        {
            this.Initialize(text, parentContext);
            this.ID = id;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="TraceContext" /> class.  ID is set based of of hash of full text.
        /// </summary>
        /// <param name="text">Text value of the context. Will be pre-pended with parent's text ID followed by a dot</param>
        /// <param name="parentContext">Parent context</param>
        internal TraceContext(string text, TraceContext parentContext)
        {
            this.Initialize(text, parentContext);
            this.ID = this.Text.GetHashCode();
        }

        /// <summary>
        /// Gets context text with inner context text, if applicable
        /// </summary>
        public string Text { get; private set; }

        /// <summary>
        /// Gets context ID that can be used for filtering
        /// </summary>
        public int ID { get; private set; }

        /// <summary>
        /// Gets parent context object
        /// </summary>
        public TraceContext ParentContext { get; private set; }

        /// <summary>
        /// Initializes Text and ParentContext
        /// </summary>
        /// <param name="text">TraceContext text.</param>
        /// <param name="parentContext">Parent context.</param>
        private void Initialize(string text, TraceContext parentContext)
        {
            this.ParentContext = parentContext;

            // Cache the name that includes parent's name. This composite name will now become this context's full name
            if (null != parentContext)
            {
                this.Text = parentContext.Text + "." + text;
            }
            else
            {
                this.Text = text;
            }
        }
    }
}
